package com.zeny.coding.controller.web;

import com.alibaba.fastjson.JSON;
import com.zeny.coding.constants.CourseConstants;
import com.zeny.coding.dto.MemberDto;
import com.zeny.coding.dto.Response;
import com.zeny.coding.dto.SmsDto;
import com.zeny.coding.enmus.SmsUseEnum;
import com.zeny.coding.service.MemberService;
import com.zeny.coding.service.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.xml.bind.ValidationException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <h2>会员</h2>
 *
 * @Author Zeny
 */
@Slf4j
@SuppressWarnings("all")
@RestController
@RequestMapping("/coding/web/member/")
public class WebMemberController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SmsService smsService;

    /**
     * <h2>注册账号</h2>
     * @param memberDto
     **/
    @PostMapping("/register")
    public Response register(@RequestBody MemberDto memberDto) throws ValidationException {
        memberDto.isValidForSave();
        //检查手机号是否已经注册
        if (memberService.isMobileExist(memberDto.getMobile())) {
            throw new RuntimeException(CourseConstants.MOBILE_REGISTRED);
        }
        //判断验证码是否正确
        SmsDto smsDto = new SmsDto();
        smsDto.setUse(SmsUseEnum.REGISTRY.getKey());
        smsDto.setMobile(memberDto.getMobile());
        SmsDto smsFromDB = smsService.findSmsByMobile(smsDto);
        if (smsFromDB == null) {
            //验证码已经失效
            throw new  RuntimeException(CourseConstants.MOBILE_CODE_INVALID);
        }
        if (!memberDto.getSmsCode().equalsIgnoreCase(smsFromDB.getCode())) {
            //验证码错误
            throw new  RuntimeException(CourseConstants.MOBILE_CODE_ERROR);
        }
        this.memberService.save(memberDto);
        return new Response().success().message(CourseConstants.MEMBER_REGISTER_SUCCESS);
    }

    /**
     * <h2>登录</h2>
     * @param userDto
     **/
    @PostMapping("/login")
    public Response login(@RequestBody MemberDto memberDto) throws ValidationException {
        memberDto.validForLogin();
        String imageCode = (String) redisTemplate.opsForValue().get(memberDto.getImageCodeToken());
        redisTemplate.delete(memberDto.getImageCodeToken());
        if (StringUtils.isEmpty(imageCode)) {
            log.info("用户登录失败");
            return new Response().fail().message(CourseConstants.IMAGECODE_EXPIRED);
        }
        if (!imageCode.toLowerCase().equals(memberDto.getImageCode().toLowerCase())) {
            log.info("用户登录失败");
            return new Response().fail().message(CourseConstants.IMAGECODE_ERROR);
        }
        MemberDto loginMember = this.memberService.login(memberDto);
        String token = UUID.randomUUID().toString();
        loginMember.setToken(token);
        redisTemplate.opsForValue().set(token, JSON.toJSONString(loginMember), 2 * 60 * 60, TimeUnit.SECONDS);
        return new Response().success().data(loginMember).message(CourseConstants.LOGIN_SUCCESS);
    }

    /**
     * <h2>重置密码</h2>
     * @param memberDto
     **/
    @PostMapping("/reset-password")
    public Response resetPassword(@RequestBody MemberDto memberDto) throws ValidationException {
        memberDto.validForResetPassword();
        //检查手机号是否已经注册
        if (!memberService.isMobileExist(memberDto.getMobile())) {
            throw new RuntimeException(CourseConstants.MOBILE_NOT_REGISTRED);
        }
        SmsDto smsDto = new SmsDto();
        smsDto.setMobile(memberDto.getMobile());
        //忘记密码
        smsDto.setUse(SmsUseEnum.FORGET.getKey());
        SmsDto smsFromDB = smsService.findSmsByMobile(smsDto);
        if (smsFromDB == null) {
            //验证码已经失效
            throw new  RuntimeException(CourseConstants.MOBILE_CODE_INVALID);
        }
        if (!memberDto.getSmsCode().equalsIgnoreCase(smsFromDB.getCode())) {
            //验证码错误
            throw new  RuntimeException(CourseConstants.MOBILE_CODE_ERROR);
        }
        memberService.updateMember(memberDto);
        return new Response().success().message(CourseConstants.RESETPASSWORD_SUCCESS);
    }

    /**
     * <h2>查询手机号是否注册了</h2>
     * @param mobile
     **/
    @GetMapping("/is-mobile-exist/{mobile}")
    public Response isMobileExist(@PathVariable("mobile") String mobile) {
        memberService.isMobileExist(mobile);
        return new Response().success();
    }
}
